Fork me on GitHub

第二章 IPC机制

2.2.1 开启多进程

  • 进程名以”:”开头的进程属于应用私有进程,其它应用不能和它跑在同一个进程,而进程名不以“:”开头的进程属于全局进程,其它应用通过ShareUID方式可以和它跑在同一进程中。(p39)

    2.2.2 多进程模式的运行机制

  • Android为每一个进程都分配了一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这就导致在不同的虚拟机中访问同一个类的对象会有不同的副本。(p40)
  • 使用多进程会造成如下几方面的问题:
  • 静态成员和单例模式完全失效
  • 线程同步机制完全失效
  • SharedPreference的可靠性下降
  • Application会多次创建

    2.3 IPC基础概念

    2.3.1 Serializable 接口

  • 需要指定serialVersionUID之后才能反序列化
  • 静态成员属于类不属于对象,所以不会参与序列化过程;用transient关键字标记的成员变量不参与序列化过程(p44)

    2.3.2 Parcelable接口

  • Parcelable是Android的序列化方式,使用略麻烦,但是效率很高
  • Serializable是Java中的序列化接口,使用简单,但开销大,序列化和反序列化过程中都需要大量的I/O操作。
  • 使用时建议:
  • 内存序列化中使用Parcelable
  • 序列化到存储设备或者将对象序列化后通过网络传输使用Serializable(P47)

    2.3.3 Binder

  • Binder是Android中的一个类,实现了IBinder接口,是Android中的一种跨进程通信方式,Linux中没有。
  • Binder主要用在Service中,包括AIDL和Messager。(P47)

    2.4 Android中的IPC方式

    2.4.1 使用Bundle

    通常情况下用Intent传递Bundle。特殊场景还可以这样用:A进程用intent启动B进程的Service组件(如IntentService),让Service在后台进行计算,计算完毕后再启动B进程中真正要启动的目标组件。

    2.4.2 使用文件共享

    通过序列化和反序列化的方式,但是要注意处理并发读/写问题,适合于对数据同步要求不高的进程间通信。

    2.4.3 使用Messenger(串行处理)

    Messager是对AIDL作了封装,底层实现是binder
    1
    2
    3
    4
    5
    6
    public Messenger(Handler target) {
    mTarget = target.getIMessenger();
    }
    public Messenger(IBinder target) {
    mTarget = IMessenger.Stub.asInterface(target);
    }
1、服务端进程

首先,需要在服务端创建一个Service来处理客户端的连接请求,同时创建一个Handler并通过它来创建一个Message对象,然后在Service的onBind中返回这个Messager对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class MessengerService extends Service {

private static final String TAG = "MessengerService";

private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MyConstants.MSG_FROM_CLIENT:
Log.i(TAG, "receive msg from Client:" + msg.getData().getString("msg"));
Messenger client = msg.replyTo;
Message relpyMessage = Message.obtain(null, MyConstants.MSG_FROM_SERVICE);
Bundle bundle = new Bundle();
bundle.putString("reply", "嗯,你的消息我已经收到,稍后会回复你。");
relpyMessage.setData(bundle);
try {
client.send(relpyMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
}
}
}

private final Messenger mMessenger = new Messenger(new MessengerHandler());

@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}

@Override
public void onCreate() {
super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}

}
2、客户端进程

客户端进程中,首先要绑定服务端的Service,绑定成功后用服务端返回的IBinder对象创建一个Messenger,通过这个Messager就可以向服务端发送消息了,发消息类型为Message对象。如果需要服务端能够回应客户端,就和服务端一样,我们还需要创建一个Handler并创建一个新的Messager,并把这个Messager对象通过Message的replyTo参数传递给服务端,服务端通过这个replyTo参数就可以回应客户端。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class MessengerActivity extends Activity {

private static final String TAG = "MessengerActivity";

private Messenger mService;
private Messenger mGetReplyMessenger = new Messenger(new MessengerHandler());

private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MyConstants.MSG_FROM_SERVICE:
Log.i(TAG, "receive msg from Service:" + msg.getData().getString("reply"));
break;
default:
super.handleMessage(msg);
}
}
}

private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mService = new Messenger(service);
Log.d(TAG, "bind service");
Message msg = Message.obtain(null, MyConstants.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg", "hello, this is client.");
msg.setData(data);
msg.replyTo = mGetReplyMessenger;
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}

public void onServiceDisconnected(ComponentName className) {
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
Intent intent = new Intent("com.ryg.MessengerService.launch");
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onDestroy() {
unbindService(mConnection);
super.onDestroy();
}
}

2.4.4 使用AIDL(可以并发,难点P71-91)

2.4.5 使用ContentProvider(P91-103)

是Android中提供的专门用于不同应用间进行数据共享的方式。
底层实现也是Binder。

2.4.6 使用Socket